home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine CD 1995 / Archive Magazine CD 1995.iso / discs / prog_disc / volume_2 / issue_06 / scott / c / xcopy < prev   
Encoding:
Text File  |  1989-01-27  |  12.4 KB  |  412 lines

  1. /* >C.Xcopy  */
  2.  
  3. /******************************************************************************
  4.   XCOPY    (c) D.J.Scott 1988
  5. *******************************************************************************
  6.   Program to perform selective backups of a hard disc
  7.  
  8.   Syntax: *XCOPY [<source path name>] [<destination path name>] [options]
  9.     Default source path name is :4.$
  10.     Default destination path name is :0.$
  11.     Options are:
  12.       -c  confirm before each item is copied or deleted from destination
  13.       -f  full copy required (default copies only files which have changed)
  14.       -r  cancel recursive option so that subdirectories are not copied
  15.       -v  cancel verbose option to suppress display information
  16. ******************************************************************************/
  17.  
  18. static char *progid = "XCOPY 1.05 - 27/01/89";
  19.  
  20. /*************************** INCLUDE DIRECTIVES ******************************/
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <signal.h>
  26. #include <arthur.h>
  27.  
  28. /*************************** DEFINE DIRECTIVES *******************************/
  29.  
  30. #define  ADFS_FreeSpace  0x40243
  31. #define  FALSE    0
  32. #define  TRUE     1
  33. #define  OPTTOT   4
  34.  
  35. /*************************** GLOBAL VARIABLES ********************************/
  36.  
  37. int copt = 0;                   /* confirm option */
  38. int fopt = FALSE;               /* full copy required option */
  39. int ropt = 1;                   /* recursive option */
  40. int vopt = 272;                 /* verbose option */
  41.  
  42. char sourc[120];                /* source path name */
  43. char destn[120];                /* destination path name */
  44.  
  45. static char *dsourc = ":4";     /* default source path name */
  46. static char *ddestn = ":0";     /* default destination path name */
  47. static char *sep = ".";         /* wild card default */
  48. static char *wild = "*";        /* wild card default */
  49.  
  50. static char *optlist[OPTTOT] =  /* option list */
  51. {
  52.   "-c",                         /* current directory only */
  53.   "-f",                         /* force overwrite and delete option */
  54.   "-r",                         /* recursive option */
  55.   "-v",                         /* verbose option */
  56. };
  57.  
  58. /*************************** FUNCTION DEFINITIONS ****************************/
  59.  
  60. void chkerr(struct error *);
  61. void copyfile(char *, char *);
  62. void escape(int);
  63. void freespc(char *);
  64. void helptext(void);
  65. void readdir(char *, char *);
  66. void setoption(char *);
  67. void wipepath(char *);
  68.  
  69. /******************************************************************************
  70. *  main           main program
  71. *      argc       number of command line parameters
  72. *      argv[]     array of parameter string pointers
  73. ******************************************************************************/
  74. int main(argc, argv)
  75.   int argc;                     /* count of command line arguments */
  76.   char *argv[];                 /* pointers to argument strings */
  77. {
  78.   static char *optchar = "-";   /* option command introducer */
  79.   int i = 1;
  80.  
  81.   signal(SIGINT, escape);
  82.  
  83.   /* process command line */
  84.   if (argc == 1)
  85.   {
  86.     /* null parameters, print program identity and help text */
  87.     helptext();
  88.     exit(0);
  89.     return(0);
  90.   }
  91.  
  92.   while (argc > i)
  93.   {
  94.     if (strncmp(optchar, argv[i], 1) == 0)
  95.     {
  96.       setoption(argv[i]);
  97.     }
  98.     else if (i == 1)
  99.     {
  100.       /* source name found */
  101.       if (strncmp(argv[1], ":", 1) != 0)
  102.       {
  103.         /* insert default drive if drive not specified */
  104.         strcpy(sourc, dsourc);
  105.         strcat(sourc, sep);
  106.         strcat(sourc, argv[1]);
  107.       }
  108.       else
  109.         strcpy(sourc, argv[1]);
  110.     }
  111.     else if (i == 2)
  112.     {
  113.       /* destination name found */
  114.       if (strncmp(argv[2], ":", 1) != 0)
  115.       {
  116.         /* insert default drive if drive not specified */
  117.         strcpy(destn, ddestn);
  118.         strcat(destn, sep);
  119.         strcat(destn, argv[2]);
  120.       }
  121.       else
  122.         strcpy(destn, argv[2]);
  123.     }
  124.     else if (i > 2)
  125.     {
  126.       fprintf(stderr, "** Unknown command parameter\n\a");
  127.       helptext();
  128.       exit(1);
  129.     }
  130.   i++;
  131.   }
  132.  
  133.   /* set default source and destination path names */
  134.   if (strlen(sourc) == 0)
  135.     strcpy(sourc, dsourc);
  136.   if (strlen(destn) == 0)
  137.     strcpy(destn, ddestn);
  138.   printf("\n");
  139.   if (fopt == TRUE)
  140.   {
  141.     strcat(sourc, sep);
  142.     strcat(sourc, wild);
  143.     strcat(destn, sep);
  144.     strcat(destn, wild);
  145.     wipepath(destn);
  146.     copyfile(sourc, destn);
  147.   }
  148.   else
  149.     readdir(sourc, destn);
  150.   destn[2] = 0;                 /* truncate destination to give drive */
  151.   freespc(destn);
  152.   exit(0);
  153.   return(0);
  154. }
  155.  
  156. /******************************************************************************
  157.   chkerr        checks for Operating System error and prints details if found
  158. ******************************************************************************/
  159. void chkerr(e)
  160.   struct error *e;
  161. {
  162.   int errno;
  163.  
  164.   if (e != 0)
  165.   {
  166.     errno = e->errnum & 0xFFF;
  167.     fprintf(stderr, "\n** %s  Error &%x\n\a", e->errmess, errno);
  168.     exit(1);                    /* terminate as fatal error */
  169.   }
  170.   return;
  171. }
  172.  
  173. /******************************************************************************
  174. *  copyfile     copy source file to destination path
  175. *       sourc           source wildcarded path name string pointer
  176. *       destn           destination wildcarded path name string pointer
  177. ******************************************************************************/
  178. void copyfile(sourc, destn)
  179.   char *sourc;
  180.   char *destn;
  181. {
  182.   reg_set cy;
  183.  
  184.   cy.r[0] = 26;
  185.   cy.r[1] = (int)sourc;         /* source path name */
  186.   cy.r[2] = (int)destn;         /* destination path name */
  187.   cy.r[3] = 2 + copt + ropt + vopt; /* action mask (F plus optionally CRV) */
  188.   chkerr(swix(OS_FSControl, &cy));
  189.   return;
  190. }
  191.  
  192. /******************************************************************************
  193.   escape
  194. ******************************************************************************/
  195. void escape(signo)
  196.   int signo;
  197. {
  198.   signal(signo, SIG_IGN);
  199.   printf("\nEscape\n");
  200.   exit(1);
  201.   return;
  202. }
  203.  
  204. /******************************************************************************
  205.   freespc       obtain and print the amount of free space left on the disc
  206.         disc            string giving the disc identity
  207. ******************************************************************************/
  208. void freespc(disc)
  209.   char *disc;
  210. {
  211.   reg_set fs;
  212.  
  213.   fs.r[0] = (int)disc;
  214.   chkerr(swix(ADFS_FreeSpace, &fs));
  215.   printf("  %d bytes free on disc %s, largest space %d bytes\n", fs.r[0], disc, fs.r[1]);
  216.   return;
  217. }
  218.  
  219. /******************************************************************************
  220. *  helptext     outputs help text
  221. ******************************************************************************/
  222. void helptext()
  223. {
  224.   printf("%30s  (c) 1988 D.J.Scott\n", progid);
  225.   printf("Selective backup program\n\n");
  226.   printf("Syntax: *XCOPY [<source path>] [<destination drive>] [options]\n");
  227.   printf("  Default source is :4\n  Default destination is 0:\n");
  228.   printf("Options are:\n");
  229.   printf("  -c  confirm before each item is copied\n");
  230.   printf("  -f  full copy, default copies only files which have changed\n");
  231.   printf("  -r  cancel recursive option, subdirectories are not copied\n");
  232.   printf("  -v  cancel verbose option, no information given about copies\n");
  233.   return;
  234. }
  235.  
  236. /******************************************************************************
  237. *  readdir      reads and displays directory contents
  238. *       snam          source directory path name string pointer
  239. *       dnam          destination directory path name string pointer
  240. ******************************************************************************/
  241. void readdir(snam, dnam)
  242.   char *snam;
  243.   char *dnam;
  244. {
  245.   char spath[250];      /* source path name string */
  246.   char dpath[250];      /* destination path name string */
  247.  
  248.   struct dirlist        /* directory list record structure */
  249.   {
  250.     int loadaddr;       /* load address */
  251.     int execaddr;       /* execution address */
  252.     int filelength;     /* file length */
  253.     int fileattrib;     /* file attributes */
  254.     int objtype;        /* object type */
  255.     char objname[12];   /* object name */
  256.   } dirlist;
  257.  
  258.   osgbpb_block db;
  259.   osfile_block dfblk, *d;
  260.   struct dirlist *s;    /* source file details pointer */
  261.  
  262.   s = &dirlist;
  263.   d = &dfblk;
  264.   /* read name and details of each item in directory */
  265.   /* set up data block for osgbpb to read directory contents */
  266.   db.action = 10;               /* read directory entries */
  267.   db.file_handle = (int)snam;   /* pointer to directory name */
  268.   db.data_addr = &dirlist;      /* address of data */
  269.   db.number = 1;                /* number of object names to read */
  270.   db.buf_len = sizeof(dirlist); /* buffer length */
  271.   db.wild_fld = wild;           /* wildcard name to match */
  272.   db.seq_point = 0;             /* offset of next item in directory */
  273.   do
  274.   {
  275.     chkerr(osgbpb(&db));        /* read directory */
  276.     if (db.number != 0 && db.seq_point >= 0)
  277.     {
  278.       if (s->objtype == 1)      /* file */
  279.       {
  280.         strcpy(spath, snam);    /* form full source file name */
  281.         strcat(spath, sep);
  282.         strcat(spath, s->objname);
  283.         strcpy(dpath, dnam);    /* form full destination file name */
  284.         strcat(dpath, sep);
  285.         strcat(dpath, s->objname);
  286.          
  287.         /* read data from file destination */
  288.         d->action = 5;
  289.         d->name = dpath;
  290.         chkerr(osfile(d));
  291.         if (d->action == 0)
  292.           copyfile(spath, dpath);
  293.         else if (d->action == 1)
  294.         {
  295.           if (d->loadaddr != s->loadaddr || d->execaddr != s->execaddr ||
  296.            d->start != s->filelength || d->end != s->fileattrib)
  297.             copyfile(spath, dpath);
  298.         }
  299.       }
  300.     }
  301.   }
  302.   while (db.seq_point >= 0);
  303.  
  304.   if (ropt == 1)
  305.   {
  306.     /* read each subdirectory and copy as well */
  307.     /* set up data block for osgbpb to reread directory contents */
  308.     db.number = 1;              /* number of object names to read */
  309.     db.wild_fld = wild;         /* wildcard name to match */
  310.     db.seq_point = 0;           /* offset of next item in directory */
  311.     do
  312.     {
  313.       chkerr(osgbpb(&db));      /* read directory */
  314.       if (db.number != 0 && db.seq_point >= 0)
  315.       {  
  316.         if (s->objtype == 2)    /* directory */
  317.         {
  318.           strcpy(spath, snam);  /* form source subdirectory pathname */                   strcat(spath, sep);
  319.           strcat(spath, s->objname);
  320.           strcpy(dpath, dnam);  /* form destination subdirectory pathname */
  321.           strcat(dpath, sep);
  322.           strcat(dpath, s->objname);
  323.  
  324.           /* check if directory exists */
  325.           d->action = 5;
  326.           d->name = dpath;
  327.           chkerr(osfile(d));
  328.           if (d->action != 2)
  329.           {
  330.             /* create the directory */
  331.             d->action = 8;
  332.             d->name = dpath;
  333.             d->start = 0;
  334.             chkerr(osfile(d));
  335.           }
  336.           readdir(spath, dpath);/* read directory contents */
  337.         }
  338.       }
  339.     }
  340.     while (db.seq_point >= 0);
  341.   }
  342.   return;
  343. }
  344.  
  345. /******************************************************************************
  346. *  setoption    decodes the option string and sets the appropriate option flag
  347. *       opt             pointer to option parameter string
  348. ******************************************************************************/
  349. void setoption(opt)
  350.   char *opt;
  351. {
  352.   int n;
  353.   int found = FALSE;
  354.  
  355.   for (n = 0; n < OPTTOT; n++)
  356.   {
  357.     if (strncmp(opt, optlist[n], 2) == 0)
  358.     {
  359.       found = TRUE;
  360.       switch(n)
  361.       {
  362.       case 0 :
  363.         copt = 8;               /* turn confirm option on */
  364.         break;
  365.       case 1 :
  366.         fopt = TRUE;            /* turn full option on */
  367.         break;
  368.       case 2 :
  369.         ropt = 0;               /* turn recursive option off */
  370.         break;
  371.       case 3 :
  372.         vopt = 0;               /* turn verbose option off */
  373.         break;
  374.       }
  375.     }
  376.   }
  377.   if (found == FALSE)
  378.   {
  379.     fprintf(stderr, "\n** Unknown option parameter\n\a");
  380.     helptext();
  381.     exit(1);
  382.   }
  383.   return;
  384. }  
  385.  
  386. /******************************************************************************
  387. *  wipepath     wipe all files from the specified path
  388. *       path    wildcarded path name string pointer
  389. ******************************************************************************/
  390. void wipepath(path)
  391.   char *path;
  392. {
  393.   osfile_block blk, *d;
  394.   reg_set wipe;
  395.  
  396.   d = &blk;
  397.   /* check if any items to delete */
  398.   d->action = 5;
  399.   d->name = path;
  400.   chkerr(osfile(d));
  401.   if (d->action != 0)
  402.   {
  403.     wipe.r[0] = 27;
  404.     wipe.r[1] = (int)path;      /* wildcarded path name */
  405.     wipe.r[3] = 2 + copt + ropt + vopt; /* action mask (F and optionally CRV) */
  406.     chkerr(swix(OS_FSControl, &wipe));  /* wipe disc */
  407.   }
  408.   return;
  409. }
  410.  
  411. /* end of file */
  412.